/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.flowable.app.rest.runtime;

import cmbchina.util.*;
import cmbchina.util.db.FlowDb;
import cmbchina.util.db.FlowFormDb;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.flowable.app.cusTaskExe.CusTaskOptParams;
import org.flowable.app.model.common.ResultListDataRepresentation;
import org.flowable.app.model.runtime.CompleteFormRepresentation;
import org.flowable.app.model.runtime.ProcessInstanceVariableRepresentation;
//import org.flowable.app.model.runtime.SaveFormRepresentation;
import org.flowable.app.service.exception.BadRequestException;
import org.flowable.app.service.runtime.FlowableTaskFormService;
import org.flowable.app.service.runtime.FlowableTaskQueryService;
import org.flowable.app.service.runtime.FlowableTaskService;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.*;
import org.flowable.engine.impl.HistoryServiceImpl;
import org.flowable.engine.impl.RepositoryServiceImpl;
import org.flowable.engine.impl.TaskServiceImpl;
import org.flowable.engine.repository.Model;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.api.FormService;
import org.flowable.form.model.FormModel;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Joram Barrez
 */
@RestController
@RequestMapping("/rest/my-task-forms")
public class CusTaskFormResource {

    private static final Logger LOGGER = LoggerFactory.getLogger(CusTaskFormResource.class);
    @Autowired
    protected FlowableTaskFormService taskFormService;
    @Autowired
    protected TaskService taskService;
    @Autowired
    protected HistoryService historyService;
    @Autowired
    protected RepositoryServiceImpl repositoryService;
    @Autowired
    protected FlowableTaskQueryService taskQueryService;
    @Autowired
    protected FormService formService;
    @Autowired
    protected FormRepositoryService formRepositoryService;

    @Autowired
    protected RuntimeService runtimeService;

    @RequestMapping(value = "/{processInstanceId}", method = RequestMethod.GET, produces = "application/json")
    public FormModel getTaskForm(@PathVariable String processInstanceId) {
        processInstanceId = "22501";
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();

        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (processInstance == null) {
            throw new BadRequestException("No process instance found with id " + "12539");
        }


        BpmnModel pojoModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        Collection<FlowElement> flowElements = pojoModel.getMainProcess().getFlowElements();
        for(FlowElement e : flowElements) {
            System.out.println("flowelement id:" + e.getId() + "  name:" + e.getName() + "   class:" + e.getClass().toString());
        }
//        String processInstanceId = "25001";
//        List<HistoricVariableInstance> list = historyService
//                .createHistoricVariableInstanceQuery().taskId(taskId)
////                .processInstanceId(processInstanceId)
//                .list();
//        if(list != null && list.size()>0){
//            for(HistoricVariableInstance hvi:list){
//                System.out.println(hvi.getId()+"    "+hvi.getVariableName()+"   "+hvi.getValue());
//            }
//        }
//        List<HistoricProcessInstance> datas = historyService
//                .createHistoricProcessInstanceQuery().finished().list();
//        System.out.println("使用finished方法：" + datas.size());
//
//
////        // 根据流程定义ID查询
////        datas = historyService.createHistoricProcessInstanceQuery()
////                .processDefinitionId(define.getId()).list();
////        System.out.println("使用processDefinitionId方法： " + datas.size());
////        // 根据流程定义key（流程描述文件的process节点id属性）查询
////        datas = historyService.createHistoricProcessInstanceQuery()
////                .processDefinitionKey(define.getKey()).list();
////        System.out.println("使用processDefinitionKey方法： " + datas.size());
////        // 根据业务主键查询
////        datas = historyService.createHistoricProcessInstanceQuery()
////                .processInstanceBusinessKey("businessKey1").list();
////        System.out.println("使用processInstanceBusinessKey方法： " + datas.size());
////        // 根据流程实例ID查询
////        datas = historyService.createHistoricProcessInstanceQuery()
////                .processInstanceId(pi1.getId()).list();
//        System.out.println("使用processInstanceId方法： " + datas.size());
//        // 查询没有完成的流程实例
//        datas = historyService.createHistoricProcessInstanceQuery().unfinished().list();
//        System.out.println("使用unfinished方法： " + datas.size());
//        java.util.Map<java.lang.String,org.flowable.engine.impl.persistence.entity.VariableInstance> map =taskService.getVariableInstances("17507");
        return taskFormService.getTaskForm(processInstanceId);
    }

    /**
     * cus function 用来根据节点的自定义id来查询任务
     * @param taskDefinitionKey
     * @param request
     * @return
     */
    @RequestMapping(value = "/elmentId/{taskDefinitionKey}", method = RequestMethod.GET, produces = "application/json")
    public HistoricTaskInstance getTaskFormByElemntId(@PathVariable String taskDefinitionKey,HttpServletRequest request) {
        String proInstId = request.getParameter("proInstId");
//        String json ="{}"
//        ObjectNode objN = new ObjectNode();
//        objN.set
//        ResultListDataRepresentation
//                taskQueryService.listTasks()
        String jsonStr = "{\"processInstanceId\":"+"}";
        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceId(proInstId).taskDefinitionKey(taskDefinitionKey).singleResult();
        HistoricVariableInstance histt=historyService.createHistoricVariableInstanceQuery().processInstanceId(proInstId).taskId(task.getId()).variableName("result").singleResult();
        if(histt==null){
//            formService..
        }
        FormModel formModel = formRepositoryService.getFormModelByKey("oneKeyInstall");
//        Model model=sqlSessionTemplate.selectOne("org.flowable.app.domain.editor.Model." + "selectModel", "e79a54da-c423-11e7-9009-005056ae6937");
        String str = (String) histt.getValue();
        return task;
    }

    /**
     * cus function 用来根据节点的自定义id来查询任务
     * @param taskDefinitionKey
     * @param request
     * @return
     */
    @RequestMapping(value = "/formModel/{taskDefinitionKey}", method = RequestMethod.GET, produces = "application/json")
    public FormModel getFormModelElemntId(@PathVariable String taskDefinitionKey,HttpServletRequest request) {
        String proInstId = request.getParameter("proInstId");

        String jsonStr = "{\"processInstanceId\":"+"}";
//        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceId(proInstId).taskDefinitionKey(taskDefinitionKey).singleResult();
//        HistoricVariableInstance histt=historyService.createHistoricVariableInstanceQuery().processInstanceId(proInstId).taskId(task.getId()).variableName("result").singleResult();
        FormModel formModel = formRepositoryService.getFormModelByKey(taskDefinitionKey);
//        Model model=sqlSessionTemplate.selectOne("org.flowable.app.domain.editor.Model." + "selectModel", "e79a54da-c423-11e7-9009-005056ae6937");
        return formModel;
    }

    /**
     * cus function 用来根据节点的自定义id来查询任务
     * @param taskDefinitionKey
     * @param request
     * @return
     */
    @RequestMapping(value = "/taskLog/{taskDefinitionKey}", method = RequestMethod.GET, produces = "application/json")
    public AjaxJson getTaskLogByElemntId(@PathVariable String taskDefinitionKey,HttpServletRequest request) {
        AjaxJson ajaxJson = new AjaxJson();
        String proInstId = request.getParameter("proInstId");

        String jsonStr = "{\"processInstanceId\":"+"}";
        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceId(proInstId).taskDefinitionKey(taskDefinitionKey).singleResult();
        HistoricVariableInstance histt=historyService.createHistoricVariableInstanceQuery().processInstanceId(proInstId).taskId(task.getId()).variableName("result").singleResult();
        String str = (String) histt.getValue();
        ajaxJson.setMsg(str);
        return ajaxJson;
    }


    @ResponseStatus(value = HttpStatus.OK)
    @RequestMapping(value = "/save-data/{taskDefinedKey}/{queryProcessInstId}", method = RequestMethod.POST, produces = "application/json")
    public AjaxJson saveData( @PathVariable String taskDefinedKey,@PathVariable String queryProcessInstId, @RequestBody CompleteFormRepresentation completeTaskFormRepresentation) throws JsonProcessingException {


        Map<String,Object> pramsMap = new LinkedHashMap<String, Object>();
        pramsMap.put("processInstId", taskDefinedKey);
        pramsMap.put("taskDefinitionKey", queryProcessInstId);
        pramsMap.put("formInfo",completeTaskFormRepresentation);
        System.out.println("save-data======="+pramsMap);
        AjaxJson ajaxJson = new AjaxJson();


        ObjectMapper obj = new ObjectMapper();
//        FlowHttpRequestUtils.httpRequestPost("/api/flow-forms/updateFormInfo", obj.writeValueAsString(pramsMap));
        FlowFormDb.updateFormInfo(obj.writeValueAsString(pramsMap),taskDefinedKey,queryProcessInstId);
        return ajaxJson;
    }

    @ResponseStatus(value = HttpStatus.OK)
    @RequestMapping(value = "/queryFormInfo/{taskDefinedKey}/{queryProcessInstId}", method = RequestMethod.GET, produces = "application/json")
    public AjaxJson queryFormInfo( @PathVariable String taskDefinedKey,@PathVariable String queryProcessInstId) throws JsonProcessingException {


        Map<String,Object> pramsMap = new LinkedHashMap<String, Object>();
        pramsMap.put("processInstId", taskDefinedKey);
        pramsMap.put("taskDefinitionKey", queryProcessInstId);
        LOGGER.error("save-data======="+pramsMap);
        AjaxJson ajaxJson = new AjaxJson();


//        FlowHttpRequestUtils.httpRequestPost("/api/flow-forms/updateFormInfo", obj.writeValueAsString(pramsMap));
        String formInfo = FlowFormDb.queryFormInfo(taskDefinedKey,queryProcessInstId);
        ajaxJson.setMsg(formInfo);
        return ajaxJson;
    }

    @ResponseStatus(value = HttpStatus.OK)
    @RequestMapping(value = "/queryFormInfoById/{taskId}", method = RequestMethod.GET, produces = "application/json")
    public AjaxJson queryFormInfo( @PathVariable String taskId) throws JsonProcessingException {


        AjaxJson ajaxJson = new AjaxJson();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();


//        FlowHttpRequestUtils.httpRequestPost("/api/flow-forms/updateFormInfo", obj.writeValueAsString(pramsMap));
        String formInfo = FlowFormDb.queryFormInfo(task.getTaskDefinitionKey(),task.getProcessInstanceId());
        ajaxJson.setMsg(formInfo);
        return ajaxJson;
    }

    @ResponseStatus(value = HttpStatus.OK)
    @RequestMapping(value = "/startProcess/{processInstanceId}", method = RequestMethod.POST, produces = "application/json")
    public AjaxJson completeTaskForm(@PathVariable String processInstanceId, @RequestBody Map<String,Object> stringObjectMap) {

//        boolean isOk = FlowFormDb.flowIsOk(processInstanceId);
//        if(!isOk){
//            ajaxJson.setSuccess(false);
//            ajaxJson.setMsg("当前流程存在未配置参数的步骤！");
//            return ajaxJson;
//        }

        AjaxJson ajaxJson = new CusTaskOptParams().optRunTaskparams(historyService,taskService,processInstanceId);
        return ajaxJson;
    }


}
